from .common import *

# Draw a bar chart.
def DrawBarFig(x_ticks, x_ticklabels, y_values, legend_labels, x_label, y_label,
               bar_width, x_min, x_max, y_min, y_max, folder, filename,
               allow_legend, color_map=COLOR_MAP, patterns=PATTERNS):
    """DrawBarFig: Function used to draw bar chart.
    \t Usage:
    \t\t x_ticks: The center x_ticks for all bars.
    \t\t x_ticklabels: Labels for the x_ticks.
    \t\t y_values: y_values for each bar.
    \t\t legend_labels: Legend labels.
    \t\t x_label: Label for the x axis.
    \t\t y_label: Label for the y axis.
    \t\t bar_width: The width of each bar.
    \t\t x_{min,max}: The min and max value along the x axis.
    \t\t y_{min,max}: The min and max value along the y axis.
    \t\t folder: The folder name.
    \t\t filename: The file name.
    \t\t allow_legend: The legend flag.
    \t\t color_map: The color map.
    \t\t patterns: The patterns.
    """
    assert(len(legend_labels) >= len(y_values))

    # you may change the figure size on your own.
    fig = plt.figure(figsize=(8, 3.2))
    figure = fig.add_subplot(111)

    # draw the bars
    bars = [None] * (len(y_values))
    num_bars = len(y_values)

    x_ticks_vec = []
    bar_pos = []
    flag = False
    if num_bars % 2 == 0:
        mid = num_bars // 2
        flag = True
        bar_pos = list(range(-1 * mid, mid, 1))

        for i in bar_pos:
            x_ticks_vec.append(x_ticks + (bar_width / 2) + bar_width * i)
    else:
        mid = num_bars // 2
        flag = False
        bar_pos = list(range(-1 * mid, mid + 1, 1))
        for i in bar_pos:
            x_ticks_vec.append(x_ticks + (bar_width * i))

    for i in range(len(y_values)):
        bars[i] = figure.bar(x_ticks_vec[i], y_values[i], bar_width,
                             hatch=patterns[i], color=color_map[i],
                             edgecolor="black", label=legend_labels[i])

    if allow_legend:
        if len(legend_labels) > 3:
            ncols = 3
            nrows = math.ceil(len(legend_labels) / ncols)
            figure.legend(bars, legend_labels, prop=LEGEND_FP, loc='upper center',
                          # ncol=len(y_values)
                          ncol=ncols, bbox_to_anchor=(0.21, 0.13 * (nrows - 1), 0.45, 1.2),
                          shadow=False, frameon=False, borderaxespad=-0.22, handlelength=2,
                          labelspacing=0.2)
        else:
            ncols = len(legend_labels)
            figure.legend(bars, legend_labels, prop=LEGEND_FP, loc='upper center',
                          # ncol=len(y_values)
                          ncol=ncols, bbox_to_anchor=(0.45, 1.2), shadow=False,
                          frameon=False, borderaxespad=-0.22, handlelength=2,
                          labelspacing=0.2)

    # draw xticks and tick labels
    plt.xticks(x_ticks, x_ticklabels)
    if isinstance(y_max, int):
        # y_ticks = np.arange(y_min, y_max, 1)
        if y_max <= 3:
            y_max = math.ceil(y_max / 0.5) * 0.5
            y_ticks = np.arange(y_min, y_max + 0.1, 0.5)
        elif y_max > 3 and y_max < 9:
            y_max = math.ceil(y_max / 1) * 1
            y_ticks = np.arange(y_min, y_max + 1, 1)
        elif y_max > 8 and y_max < 16:
            y_max = math.ceil(y_max / 2) * 2
            y_ticks = np.arange(y_min, y_max + 1, 2)
        elif y_max > 15 and y_max < 22:
            y_max = math.ceil(y_max / 3) * 3
            y_ticks = np.arange(y_min, y_max + 1, 3)
        elif y_max > 21 and y_max < 32:
            y_max = math.ceil(y_max / 4) * 4
            y_ticks = np.arange(y_min, y_max + 1, 4)
        else:
            y_max = math.ceil(y_max / 5) * 5
            y_ticks = np.arange(y_min, y_max + 1, 5)

        plt.yticks(y_ticks, y_ticks)
    else:
        if y_max < 3.0:
            y_max = math.ceil(y_max / 0.5) * 0.5
            y_ticks = np.arange(y_min, y_max + 0.1, 0.5)
        elif y_max < 8.0:
            y_max = math.ceil(y_max / 1.0) * 1.0
            y_ticks = np.arange(y_min, y_max + 0.1, 1.0)
        else:
            y_max = math.ceil(y_max / 2.0) * 2.0
            y_ticks = np.arange(y_min, y_max + 0.1, 2.0)
        plt.yticks(y_ticks, y_ticks)

    plt.xlim(x_min, x_max)
    plt.ylim(y_min, y_max)

    figure.grid(axis='y', color='gray', linestyle='--')
    # figure.yaxis.set_major_locator(LinearLocator(6))

    figure.get_xaxis().set_tick_params(direction='in', pad=10)
    figure.get_yaxis().set_tick_params(direction='in', pad=10)

    plt.xlabel(x_label, fontproperties=LABEL_FP)
    plt.ylabel(y_label, fontproperties=LABEL_FP)

    if not folder and not filename:
        plt.show()
    else:
        if not os.path.exists(folder):
            os.makedirs(folder)
        plt.savefig(folder + "/" + filename + ".eps", bbox_inches='tight',
                format='eps')
